package com.ruoyi.points.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.points.dao.IPointsChangeRecordDao;
import com.ruoyi.points.domain.PointsChangeRecord;
import com.ruoyi.points.service.IUserCheckinService;

/**
 * 用户签到Service业务层处理
 *
 * @author 区嘉盛
 * @date 2025-06-20
 */
@Service
public class UserCheckinServiceImpl implements IUserCheckinService {

    @Autowired
    private IPointsChangeRecordDao pointsChangeRecordDao;

    /**
     * 签到奖励积分
     */
    private static final Long CHECKIN_POINTS = 1L;

    /**
     * 签到积分变动来源类型
     */
    private static final Long CHECKIN_SOURCE_TYPE = 10L;

    /**
     * 用户签到
     *
     * @param userId 用户ID
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult doCheckin(Long userId) {
        // 检查用户今天是否已经签到
        if (hasCheckedInToday(userId)) {
            return AjaxResult.error("今天已经签到过了，请明天再来签到！");
        }
        
        int result = pointsChangeRecordDao.recordAndUpdatePoints(userId, CHECKIN_POINTS, CHECKIN_SOURCE_TYPE, null);
        if (result <= 0) {
            return AjaxResult.error("签到失败，用户不存在或积分记录异常");
        }
        
        return AjaxResult.success("签到成功，获得" + CHECKIN_POINTS + "积分");
    }
    
    /**
     * 检查用户今天是否已经签到
     *
     * @param userId 用户ID
     * @return 是否已签到
     */
    private boolean hasCheckedInToday(Long userId) {
        // 获取今天的开始时间和结束时间
        LocalDate today = LocalDate.now();
        LocalDateTime startOfDay = today.atStartOfDay();
        LocalDateTime endOfDay = today.atTime(23, 59, 59);
        
        // 查询今天是否有签到记录
        QueryWrapper<PointsChangeRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId)
                   .eq("change_source_type", CHECKIN_SOURCE_TYPE)
                   .ge("created_time", startOfDay)
                   .le("created_time", endOfDay)
                   .eq("deleted_flag", 0);
        
        long count = pointsChangeRecordDao.count(queryWrapper);
        return count > 0;
    }
}